package com.cuiweiyou.gimmick;

import com.huaban.analysis.jieba.JiebaSegmenter;
import com.huaban.analysis.jieba.SegToken;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class TalkMaster {
    private static TalkMaster instance;

    private List<GimmickBean> gimmickList; // 话术文案
    private JiebaSegmenter segmenter;

    private TalkMaster() {
        segmenter = new JiebaSegmenter();
    }

    public static TalkMaster getInstance() {
        if (null == instance) {
            synchronized (TalkMaster.class) {
                if (null == instance) {
                    instance = new TalkMaster();
                }
            }
        }
        return instance;
    }

    public void setGimmickList(List<GimmickBean> list) {
        gimmickList = new ArrayList<>();
        gimmickList.addAll(list);
    }

    /**
     * 根据客户的语句，返回回复语句
     *
     * @param list
     * @return
     */
    public List<String> getAnswer(List<String> list) {
        ArrayList<String> otherMsgList = new ArrayList<>();
        otherMsgList.addAll(list);

        List<String> answerList = new ArrayList<>();

        System.out.println("对方的消息数量：" + otherMsgList.size());

        if (otherMsgList.size() > 0) {

            // 打招呼语句处理
            boolean hasHelloWord = false;
            for (int i = 0; i < list.size(); i++) {
                String omsg = list.get(i);

                System.out.println("对方消息处理：" + omsg);
                if (!"_+_".equals(omsg)) { // 对方的消息拿到了
                    boolean isHelloWord = WordManager.getInstance()
                                                     .isHelloWord(omsg);
                    if (isHelloWord) { // 是固定的打招呼句式
                        otherMsgList.remove(omsg);

                        if (!hasHelloWord) { // 已经有
                            String answerMsg = WordManager.getInstance()
                                                          .getRandomGimmickMsg();// 打招呼固定句式的回复
                            answerList.add(answerMsg);
                            hasHelloWord = true;
                        }
                    }
                }
            }

            if (otherMsgList.size() < 1) {
                return answerList;
            }

            // 有意义语句处理
            List<String> tmpAnswer = new ArrayList<>();
            for (int i = 0; i < otherMsgList.size(); i++) {
                String question = otherMsgList.get(i);
                if (!"_+_".equals(question)) { // 对方的消息拿到了

                    GimmickBean gimmickModel = getGimmickModel(question);// 直接匹配话术
                    if (null != gimmickModel) {
                        // 1.为话术取一个回复
                        String index = getRandomAnswerGimmickIndex(gimmickModel);

                        // 2.取回复
                        GimmickBean gimmick = getGimmick(index); // 直接匹配到的话术取回复
                        String answer = gimmick.getGimmick();

                        // 3.保存
                        if (!tmpAnswer.contains(answer)) {
                            tmpAnswer.add(answer);
                        }

                        continue;
                    }

                    // 1.去掉无意义词汇
                    String msg = WordManager.getInstance()
                                            .delNormalOtherWord(question);

                    if (null == msg || msg.length() < 1) {
                        continue;
                    }

                    // 2.提取固定词汇
                    List<String> fixedWord = WordManager.getInstance()
                                                        .getFixedWord(msg);
                    // 3.结巴分词
                    List<SegToken> segList = segmenter.process(msg, JiebaSegmenter.SegMode.INDEX);
                    List<String> dividedList = new ArrayList<>();
                    for (int j = 0; j < segList.size(); j++) {
                        SegToken seg = segList.get(j);
                        dividedList.add(seg.word);
                    }

                    // 4.提取近义词
                    List<String> homoionymWord = new ArrayList<>();
                    for (int j = 0; j < fixedWord.size(); j++) {
                        String word = fixedWord.get(j);
                        List<String> hList = WordManager.getInstance()
                                                        .getHomoionymWord(word);
                        homoionymWord.addAll(hList);
                    }

                    // 5.匹配话术
                    List<String> keyWordList = new ArrayList<>();
                    for (int j = 0; j < keyWordList.size(); j++) {
                        String word = keyWordList.get(j);
                        if (!keyWordList.contains(word)) {
                            keyWordList.add(word);
                        }
                    }
                    for (int j = 0; j < dividedList.size(); j++) {
                        String word = dividedList.get(j);
                        if (!keyWordList.contains(word)) {
                            keyWordList.add(word);
                        }
                    }
                    for (int j = 0; j < homoionymWord.size(); j++) {
                        String word = homoionymWord.get(j);
                        if (!keyWordList.contains(word)) {
                            keyWordList.add(word);
                        }
                    }
                    System.out.println("最终分词：" + keyWordList.toString());
                    GimmickBean model = getUnFixedSentences(keyWordList);

                    // 6.为话术取一个回复
                    String index = getRandomAnswerGimmickIndex(model);

                    // 7.取回复
                    String answer = "";
                    GimmickBean gimmick = getGimmick(index); // 分词匹配后拿到的话术进行回复
                    if (null != gimmick) {
                        answer = gimmick.getGimmick();
                    }

                    // 8.保存
                    if (!"".equals(answer) && !tmpAnswer.contains(answer)) {
                        answer = WordManager.getInstance()
                                            .getPrefixAnswerMsg() + answer;
                        tmpAnswer.add(answer);
                    }
                }
            }

            answerList.addAll(tmpAnswer);

            if (answerList.size() < 1) { // 如果对方的多个消息都没有匹配到
                String emptyAnswer = WordManager.getInstance()
                                                .getRandomEmptyAnswerMsg();// 返回一个随意聊天消息
                System.out.println("随意聊天消息：" + emptyAnswer);
                answerList.add(emptyAnswer);
            }

        } else { // 对方没有真人消息，为默认系统提示消息
            String answerMsg = WordManager.getInstance()
                                          .getRandomEmptyAnswerMsg(); // 固定句式回复，对方消息为空
            answerList.add(answerMsg);
        }

        return answerList;
    }

    // 直接看看这句话是不是在话术文案里
    private GimmickBean getGimmickModel(String string) {
        for (int j = 0; j < gimmickList.size(); j++) {
            GimmickBean bean = gimmickList.get(j);
            String text = bean.getGimmick()
                              .trim();

            if ("other".equals(bean.getSide())) {
                if (string.equals(text)) {
                    System.out.println("匹配到了相同语句：" + bean);
                    return bean;
                }
            }
        }

        return null;
    }

    /**
     * 根据词汇匹配话术<br/>
     * 匹配到的词汇越多，越优先返回
     *
     * @param wordList 词汇集合
     * @return
     */
    private GimmickBean getUnFixedSentences(List<String> wordList) {
        if (null == wordList || wordList.size() < 1) {
            return null;
        }

        Map<GimmickBean, Integer> mateMap = new HashMap<>();       // 记录一句话术匹配到的词汇数量
        Map<String, List<GimmickBean>> countMap = new HashMap<>(); // 按匹配数量记录话术
        for (int j = 0; j < gimmickList.size(); j++) {
            GimmickBean bean = gimmickList.get(j);

            if ("other".equals(bean.getSide())) {
                String text = bean.getGimmick();

                int segmenterCount = 0;
                for (int i = 0; i < wordList.size(); i++) {
                    String word = wordList.get(i);
                    if (text.equals(word) || text.contains(word) || word.contains(text)) {
                        segmenterCount++;
                        System.out.println("匹配到的分词：" + word);
                    }
                }

                System.out.println("匹配词汇量：" + segmenterCount + "，" + bean);

                // 这一句话术，匹配到了segmenterCount个分词
                if (segmenterCount > 0) {
                    mateMap.put(bean, segmenterCount);
                }

                List<GimmickBean> beanList = countMap.get(segmenterCount + "");
                if (null == beanList) {
                    beanList = new ArrayList<>();
                    countMap.put(segmenterCount + "", beanList);
                }

                // 在 匹配到segmenterCount个分词 的这一组里存入此话术
                beanList.add(bean);
            }
        }

        int sizeCount = countMap.size(); // 匹配个数 的分组数量。map的key即匹配的个数
        int sizeMate = mateMap.size();   // 被匹配到的话术。1表示只有一条话术可用
        if (1 == sizeCount && sizeMate > 0) { // 话术匹配的次数都是一样的，并且是多条话术
            String count = countMap.keySet()
                                   .iterator()
                                   .next();
            System.out.println("分词匹配次数一样：" + count);
            GimmickBean[] keys = mateMap.keySet()
                                        .toArray(new GimmickBean[0]);
            GimmickBean randomKey = keys[new Random().nextInt(keys.length)]; // 随机选一条适配
            return randomKey;
        }

        // 如果匹配到了多条，且次数不一样
        if (!mateMap.isEmpty()) {
            Iterator<GimmickBean> iterator = mateMap.keySet()
                                                    .iterator();
            GimmickBean result = null;
            int count = 0;
            while (iterator.hasNext()) {
                GimmickBean next = iterator.next();
                int integer = mateMap.get(next)
                                     .intValue();
                if (integer > count) {
                    count = integer;
                    result = next;
                }
            }

            System.out.println("最接近对方话术的是：" + result);

            return result;
        }

        System.out.println("未匹配到的对方话术索引");
        return null;
    }

    // 为对方的非固定句式消息匹配一个回复，返回回复话术的索引
    private String getRandomAnswerGimmickIndex(GimmickBean gimmick) {
        if (null == gimmick) {
            return null;
        }

        List<String> next = gimmick.getNextIndexList();
        int i1 = new Random().nextInt(next.size()); // 回答话术的索引
        String index = next.get(i1);
        System.out.println("挑选一个回复话术的索引：" + index);

        if ("-1".equals(index)) {
            return null;
        }

        return index;
    }

    // 根据索引提取一个话术
    private GimmickBean getGimmick(String answerIndex) {
        if (null == answerIndex) {
            return null;
        }

        for (int k = 0; k < gimmickList.size(); k++) {
            GimmickBean sb = gimmickList.get(k);
            String index = sb.getIndex();
            if (index.equals(answerIndex)) {
                System.out.println("根据索引提取一个话术：" + sb);
                return sb;
            }
        }

        System.out.println("未能根据索引提取一个话术");
        return null;
    }

}
